package lianxi7;

import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

import static lianxi7.ParallelStreamsHarness.FORK_JOIN_POOL;

public class ForkJoinSumCalculator extends RecursiveTask<Long> {
	
	public static final long THRESHOLD= 10_000;
	
	/**
	 * 数组内容
	 */
	private final  long[] numbers;
	
	/**
	 * 数据开始
	 */
	private final int start ;
	
	private final int end;
	
	public ForkJoinSumCalculator(long[] numbers){
		this(numbers,0,numbers.length);
	}
	
	public ForkJoinSumCalculator(long[] numbers,int start ,int end){
		this.numbers =numbers;
		this.start=start;
		this.end=end;
	}
	
	
	/**
	 * 其中 RecursiveTask  是有返回结果的 如果不返回 结果 那就使用 RecursiveAction 类型
	 * 
	 */
	@Override
	protected Long compute() {
		int length = end-start;
		if(length <=THRESHOLD){
			return computeSequentially();
		}
		
		ForkJoinSumCalculator  leftTask =new ForkJoinSumCalculator(numbers, start, start+length/2);
		leftTask.fork();
		ForkJoinSumCalculator  rightTask=new ForkJoinSumCalculator(numbers,start+length/2,end);
		
		long  rightResult =rightTask.compute();
		
		long  leftResult =leftTask.join();

		return rightResult+leftResult;
	}

	
	private long computeSequentially(){
		long sum =0; 
		for(int i=start;i<end;i++){
			sum+=numbers[i];
		}
		return sum;
	}
	
	public static long forkJoinSum(long n){
		long[]  numbers =LongStream.rangeClosed(1, n).toArray();
		ForkJoinTask<Long> task =new ForkJoinSumCalculator(numbers);
		return FORK_JOIN_POOL.invoke(task);
	}
}
